package com.nsharmon.model.transformer;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import com.nsharmon.dao.entity.Axiom;
import com.nsharmon.dao.entity.EntityObject;
import com.nsharmon.dao.entity.EqualityAxiom;

public class EqualityTransformer implements Transformer {

	@Override
	public boolean transformBegin() {
		return true;
	}
	
	@Override
	public Set<Axiom> transform(Set<Axiom> axioms) {
		Set<Axiom> generatedAxioms = new LinkedHashSet<Axiom>();
		for(Axiom axiom : axioms) {
			if(axiom instanceof EqualityAxiom) {
				EqualityAxiom ea = (EqualityAxiom)axiom;
				
				applyEqualityAxiom(axioms, generatedAxioms, ea);
			}
		}
		return generatedAxioms;
	}

	@Override
	public Set<Axiom> transformEnd( Set<Axiom> axioms ) {
		return null;
	}
	
	public void applyEqualityAxiom(Set<Axiom> axioms,
			Set<Axiom> generatedAxioms, EqualityAxiom ea) {
		for(EntityObject eo : ea.getEntities()) {
			Set<Axiom> nonEqualityAxioms = getNonEqualityAxiomsByEntity(axioms, eo);
			
			for(Axiom nonEqualityAxiom : nonEqualityAxioms) {
				for(EntityObject eo2 : ea.getEntities()) {
					if(!eo.equals(eo2)) {
						Axiom clonedAxiom = nonEqualityAxiom.clone();
						clonedAxiom.replace(eo, eo2);
						
						if(!axioms.contains(clonedAxiom)) {
							generatedAxioms.add(clonedAxiom);
						}
					}
				}
			}
		}
	}

	private static Set<Axiom> getNonEqualityAxiomsByEntity(Set<Axiom> axioms, EntityObject eo) {
		Set<Axiom> nonEqualityAxioms = new LinkedHashSet<Axiom>();
		for(Axiom axiom : axioms) {
			if(!(axiom instanceof EqualityAxiom)) {
				List<EntityObject> entities = axiom.getEntities();
				for(EntityObject eoAxiom : entities) {
					if(eoAxiom.equals(eo)) {
						nonEqualityAxioms.add(axiom);
					}
				}
			}
		}
		return nonEqualityAxioms;
	}
}
